﻿using Manon.ConfigCenter.Output;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

namespace Manon.ConfigCenter
{
    public class ConfigCenterHelper
    {

        /// <summary>
        /// 获取配置中心相关配置configcenter.json
        /// </summary> 
        /// <returns></returns>
        public static T GetCenterConfig<T>() where T : class, new()
        {
            var baseDir = AppContext.BaseDirectory;

            string settingPath = $"configcenter.json";
            if (!File.Exists(settingPath))
            {
                throw new Exception("configcenter.json配置文件不存在!");
            }
            return ReadLocalJson<T>(Path.Combine(baseDir, settingPath), "");
        }

        /// <summary>
        /// 获取自定义配置文件配置
        /// </summary>
        /// <typeparam name="T">配置模型</typeparam>
        /// <param name="key">根节点</param>
        /// <param name="configPath">配置文件名称</param>
        /// <returns></returns>
        public static T GetConfig<T>(string secretPath = null) where T : class, new()
        {
            var baseDir = AppContext.BaseDirectory;
            var currentClassDir = baseDir;

            string settingPath = $"appsettings.json";
            if (!string.IsNullOrEmpty(secretPath))
            {
                settingPath = secretPath;
            }

            if (!File.Exists(settingPath))
            {
                throw new Exception("appsettings.json配置文件不存在!");
            }
            return ReadLocalJson<T>(settingPath, "");
        }


        /// <summary>
        /// 根据节点读取Json返回实体对象
        /// </summary>
        /// <returns></returns>
        private static T ReadLocalJson<T>(string path, string section)
        {
            using (var file = new StreamReader(path))
            using (var reader = new JsonTextReader(file))
            {
                var jObj = JToken.ReadFrom(reader);
                if (jObj is Newtonsoft.Json.Linq.JArray)
                {
                    return JsonConvert.DeserializeObject<T>(jObj.ToString());
                }
                if (!string.IsNullOrWhiteSpace(section))
                {
                    var secJt = jObj[section];
                    if (secJt != null)
                    {
                        return JsonConvert.DeserializeObject<T>(secJt.ToString());
                    }
                }
                else
                {
                    return JsonConvert.DeserializeObject<T>(jObj.ToString());
                }
                return default(T);
            }
        }

        /// <summary>
        /// 加载配置
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T loadSettings<T>() where T : ConfigCenterBaseOutput, new()
        {

            ConfigCenterBaseOutput center = GetCenterConfig<ConfigCenterBaseOutput>();
            if (center == null)
            {
                throw new Exception("找不到configcenter.json文件");
            }
            T model = new T();
            if (!center.UseConfigCenter)
            {
                model = GetConfig<T>(center.SecretPath);
            }
            else
            {
                model = loadSettings<T>(center);
            }
            model.ProjectCode = center.ProjectCode;
            model.ClientId = center.ClientId;
            model.ClientSecretKey = center.ClientSecretKey;
            model.EnvCode = center.EnvCode;
            model.Path = center.Path;
            model.AspnetCoreEnvironment = center.AspnetCoreEnvironment;
            model.UseConfigCenter = center.UseConfigCenter;
            model.SecretPath = center.SecretPath;
            return model;
        }

        /// <summary>
        /// 加载配置中心配置
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="center"></param>
        /// <returns></returns>
        public static T loadSettings<T>(ConfigCenterBaseOutput center) where T : ConfigCenterBaseOutput, new()
        {
            string code = $"{center.ClientId}:{center.ClientSecretKey}";
            byte[] bytes = Encoding.UTF8.GetBytes(code);
            string authstring = Convert.ToBase64String(bytes);
            var client = new HttpClient();
            string requestUrl = $"/api/config/default/{center.EnvCode}/{center.ProjectCode}";
            client.BaseAddress = new Uri(center.Path);
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authstring);
            var httpResult = client.GetAsync(requestUrl).GetAwaiter().GetResult();
            if (!httpResult.IsSuccessStatusCode)
            {
                throw new Exception("配置中心加载失败");
            }
            string strSettings = httpResult.Content.ReadAsStringAsync().Result;
            ConfigCenterOutput<string> settingsData = JsonConvert.DeserializeObject<ConfigCenterOutput<string>>(strSettings);
            if (settingsData != null && !string.IsNullOrEmpty(settingsData.data))
            {
                byte[] c = Convert.FromBase64String(settingsData.data);
                strSettings = System.Text.Encoding.Default.GetString(c);
            }
            T settings = JsonConvert.DeserializeObject<T>(strSettings);
            return settings;
        }
    }
}
